home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / telecomm / sticpsrc.lzh / SOURCE.ARC / SCCVEC.S < prev    next >
Text File  |  1989-03-20  |  6KB  |  174 lines

  1. /
  2. / SCC interrupt handler for Atari ST
  3. /
  4. / exported functions and variables
  5. /
  6.     .globl    sccvec_,sccnovec_
  7.     .globl    scctvec_,sccotvec_,scctim_
  8. /
  9. / variables from C
  10. /
  11.     .globl    sccvecloc_,sccmaxvec_,sccpolltab_,sccchan_
  12.     .globl    sccisrloc_,sccisrbit_,sccgpiploc_,sccgpipbit_
  13. /
  14.     .shri
  15. /
  16. / sccvec is the interrupt handler for SCC interrupts using INTACK
  17. /
  18. sccvec_:
  19.     movem.l ${d0-d2,a0-a2},-(sp)    / Save C working registers
  20. /
  21. / Determine if an interrupt request is really coming in from SCC
  22. /
  23.     movea.l sccgpiploc_,a0        / Location of GPIP register
  24.     move.w    sccgpipbit_,d0        / Bit number to test
  25.     btst    d0,(a0)            / Test bit in GPIP data register
  26.     bne.s    clrisr            / No interrupt, clear ISR & iret
  27. /
  28. / Read SCC interrupt vector and check it
  29. /
  30. sccint: movea.l sccvecloc_,a0
  31.     move.b    $0xff,(a0)        / Generate INTACK
  32.     bra    delay            / Short delay
  33. delay:
  34.     move.b    (a0),d0            / Read the vector
  35.     cmp.b    sccmaxvec_,d0        / Check for a legal vector
  36.     bhs.s    panic            / It should not be >= the maximum
  37. /
  38. / Extract channel number and status from vector. Determine handler address.
  39. /
  40.     move.b    d0,d1            / Save vector to retrieve status
  41.     lsr.b    $1,d0            / Discard least significant bit
  42.     bcs.s    panic            / It should not be a 1
  43.     andi.w    $0x7c,d0        / Isolate channel number (and make word)
  44.     eori.w    $0x04,d0        / Toggle A/B channel bit
  45.     lea    sccchan_,a0        / Address SCC channel table
  46.     movea.l 0(a0,d0),a0        / Read address of channel structure
  47.     move.l    a0,d0            / Make sure this is an attached channel
  48.     beq.s    panic            / No channel struct, problems...
  49.     andi.w    $0x06,d1        / Isolate status info from vector
  50.     lsl.w    $1,d1            / Make index in LONG array
  51.     movea.l 0(a0,d1),a1        / Read the interrupt handler address
  52. /
  53. / Call the handler (defined in C), with sccchan struct as a parameter
  54. /
  55.     move.l    a0,-(sp)        / Put channel struct as a parameter
  56.     jsr    (a1)            / Call the handler
  57.     movea.l (sp)+,a0        / Get channel struct back
  58.                     / Assumes C routine does not change it
  59. /
  60. / Reset highest priority interrupt
  61. /
  62.     movea.l 16(a0),a1        / Get control register address
  63.     move.b    $0x38,(a1)        / "Reset Highest IUS" opcode to WR0
  64. /
  65. / Clear the ISR bit in the MFP
  66. /
  67. clrisr: movea.l sccisrloc_,a0        / Location of ISR
  68.     move.w    sccisrbit_,d0        / Bit number to clear
  69.     bclr    d0,(a0)            / Clear the bit
  70. /
  71. / Determine if more interrupt requests are coming in from the SCCs
  72. /
  73.     movea.l sccgpiploc_,a0        / Location of GPIP register
  74.     move.w    sccgpipbit_,d0        / Bit number to test
  75.     btst    d0,(a0)            / Test bit in GPIP data register
  76.     beq.s    sccint            / Is active, handle next SCC interrupt
  77. /
  78. / Restore registers and return from interrupt handler
  79. /
  80. iret:    movem.l (sp)+,${d0-d2,a0-a2}    / Restore registers
  81.     rte
  82. /
  83. / Branch to here when irrecoverable errors occur in the interrupt handler
  84. /
  85. panic:    illegal                / This will cause a TRAP
  86.     movea.l sccisrloc_,a0        / On continuation, clear it and return
  87.     move.w    sccisrbit_,d0        / Bit number to clear
  88.     bclr    d0,(a0)            / Clear the bit
  89.     bra    iret
  90. /
  91. /
  92. / sccnovec is the interrupt handler for SCC interrupts using polling
  93. /
  94. sccnovec_:
  95.     movem.l ${d0-d2,a0-a2},-(sp)    / Save C working registers
  96. /
  97. / Determine if an interrupt request is really coming in from SCC
  98. /
  99.     movea.l sccgpiploc_,a0        / Location of GPIP register
  100.     move.w    sccgpipbit_,d0        / Bit number to test
  101.     btst    d0,(a0)            / Test bit in GPIP data register
  102.     bne.s    clrisrnv        / No interrupt, clear ISR & iret
  103. /
  104. / Find the SCC generating the interrupt by polling all attached SCCs
  105. / reading RR3A (the interrupt pending register)
  106. /
  107. sccintnv:
  108.     movea.l $sccpolltab_,a0        / Point to polling table
  109. sccpoll:
  110.     move.l    (a0)+,d0        / Get chan A CTRL address
  111.     beq.s    panic            / End of table, we did not find it!
  112.     movea.l d0,a1            / Move it to an address register
  113.     movea.l (a0)+,a2        / Also read B CTRL address
  114.     move.b    $3,(a1)            / Select RR3A
  115.     move.b    (a1),d0            / Read it and test for 0
  116.     beq.s    sccpoll            / No interrupt here, try next chip
  117. /
  118. / Read SCC interrupt vector from RR2B, it should always be correct
  119. / Extract channel number and status from vector. Determine handler address.
  120. /
  121.     move.b    $2,(a2)            / Select RR2B
  122.     move.b    (a2),d0            / Read the vector
  123.     move.b    d0,d1            / Save vector to retrieve status
  124.     lsr.b    $1,d0            / Discard least significant bit
  125.     andi.w    $0x7c,d0        / Isolate channel number (and make word)
  126.     eori.w    $0x04,d0        / Toggle A/B channel bit
  127.     lea    sccchan_,a0        / Address SCC channel table
  128.     movea.l 0(a0,d0),a0        / Read address of channel structure
  129.     move.l    a0,d0            / Make sure this is an attached channel
  130.     beq.s    panic            / No channel struct, problems...
  131.     andi.w    $0x06,d1        / Isolate status info from vector
  132.     lsl.w    $1,d1            / Make index in LONG array
  133.     movea.l 0(a0,d1),a1        / Read the interrupt handler address
  134. /
  135. / Call the handler (defined in C), with sccchan struct as a parameter
  136. /
  137.     move.l    a0,-(sp)        / Put channel struct as a parameter
  138.     jsr    (a1)            / Call the handler
  139.     addq.l    $4,sp            / Remove parameter
  140. /
  141. / Clear the ISR bit in the MFP
  142. /
  143. clrisrnv:
  144.     movea.l sccisrloc_,a0        / Location of ISR
  145.     move.w    sccisrbit_,d0        / Bit number to clear
  146.     bclr    d0,(a0)            / Clear the bit
  147. /
  148. / Determine if more interrupt requests are coming in from the SCCs
  149. /
  150.     movea.l sccgpiploc_,a0        / Location of GPIP register
  151.     move.w    sccgpipbit_,d0        / Bit number to test
  152.     btst    d0,(a0)            / Test bit in GPIP data register
  153.     beq.s    sccintnv        / Is active, handle next SCC interrupt
  154. /
  155. / Restore registers and return from interrupt handler
  156. /
  157.     movem.l (sp)+,${d0-d2,a0-a2}    / Restore registers
  158.     rte
  159. /
  160. /
  161. / This routine will be inserted in the 200Hz timer interrupt handling
  162. / (vector 0x114) to call the SCC driver timing routine every 2nd
  163. / interrupt (= every 10 ms), and thereafter jump to the original handler
  164. /
  165. scctvec_:
  166.     btst    $0,0x4bd        / Test low bit of 200Hz counter
  167.     beq.s    punt            / Not our turn
  168.     movem.l ${d0-d2,a0-a2},-(sp)    / Save C working registers
  169.     jsr    scctim_            / Call C routine every 10 ms
  170.     movem.l (sp)+,${d0-d2,a0-a2}    / Restore registers
  171. punt:    jmp    0xeeeeeeee        / Jump to original handler
  172. sccotvec_ =    .-4            / Original hander address stored here
  173.  
  174.